package com.xbongbong.saas.script.help;

import com.alibaba.fastjson.JSONArray;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DefaultTypeEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.factory.FieldOptimizationHandle;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkedAttrPoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.service.HandleFieldEntity4InitService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.fundset.pojo.FundSetHandleExplainPojo;
import com.xbongbong.pro.fundset.pojo.FundSetTransitionPojo;
import com.xbongbong.saas.base.EnumBase;
import com.xbongbong.saas.config.SpringContextUtil;
import com.xbongbong.saas.enums.CustomerStatementProductEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.product.AssembleInProductEnum;
import com.xbongbong.saas.enums.product.AssembleProductEnum;
import com.xbongbong.saas.enums.product.BomFinishProductEnum;
import com.xbongbong.saas.enums.product.BomMaterielProductEnum;
import com.xbongbong.saas.enums.product.ContractOutstockProductEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.enums.product.CostAdjustProductEnum;
import com.xbongbong.saas.enums.product.InstockProductEnum;
import com.xbongbong.saas.enums.product.InventoryProductEnum;
import com.xbongbong.saas.enums.product.OpportunityProductEnum;
import com.xbongbong.saas.enums.product.OriStockProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionInstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderFinishProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderMaterielProductEnum;
import com.xbongbong.saas.enums.product.PromotionActivityManagementProductEnum;
import com.xbongbong.saas.enums.product.PurchaseInstockProductEnum;
import com.xbongbong.saas.enums.product.PurchaseProductEnum;
import com.xbongbong.saas.enums.product.QuotationProductEnum;
import com.xbongbong.saas.enums.product.RefundInstockProductEnum;
import com.xbongbong.saas.enums.product.RefundProductEnum;
import com.xbongbong.saas.enums.product.ReturnPurchaseProductEnum;
import com.xbongbong.saas.enums.product.ReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.enums.product.ReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.enums.product.SupplierProductEnum;
import com.xbongbong.saas.enums.product.TransferProductEnum;
import com.xbongbong.saas.enums.product.WorkOrderOutstockProductEnum;
import com.xbongbong.saas.enums.product.WorkOrderProductEnum;
import com.xbongbong.saas.script.pojo.LinkProductInitFieldPoJo;
import com.xbongbong.saas.script.tempenum.DemoEnum;
import com.xbongbong.saas.script.tempenum.DemoIconEnum;
import com.xbongbong.saas.script.tempenum.TempCustomerStatementProductEnum;
import com.xbongbong.saas.script.tempenum.TempProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempAssembleInProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempAssembleProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempBomFinishProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempBomMaterieProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempContractOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempContractProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempCostAdjustProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempInventoryProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempOpportunityProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempOriStockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionOrderFinishProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionOrderMaterieProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempPromotionActivityManagementProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempPurchaseInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempPurchaseProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempQuotationProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempRefundInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempRefundProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnPurchaseProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempSupplierProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempTransferProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempWorkOrderOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempWorkOrderProductEnum;
import com.xbongbong.saas.service.FundSetService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 字段解释初始化帮助类
 * @author kaka
 */
public class InitExplainsHelper extends SaasInitExplainsHelper {

    private static final Logger LOG = LoggerFactory.getLogger(InitExplainsHelper.class);

    private static final String FUND_SERVICE_BEAN_ID = "fundSetService";
    private static final String HANDLEFIELDENTITY4INIT_SERVICE_BEAN_ID = "handleFieldEntity4InitService";

    private static final List<Integer> DISTRIBUTOR_BUSINESSTYPE = Arrays.asList(XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.REFUND.getCode(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode());

    /**
     * 这些业务，初始化字段为空数组
     */
    public static final List<Integer> EMPTY_EXPLAIN = Arrays.asList(
            // CRM
            XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), XbbRefTypeEnum.CONTACT.getCode(), XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(),
            XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.QUOTATION.getCode(), XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.REFUND.getCode(),
            XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(),
            // 联系人表单下项目决策信息
            XbbRefTypeEnum.PROJECT_DECISION_INFO.getCode(),
            // 进销存
            XbbRefTypeEnum.SUPPLIER.getCode(), XbbRefTypeEnum.SUPPLIER_CONTACT.getCode(), XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode(), XbbRefTypeEnum.PURCHASE.getCode(),
            XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), XbbRefTypeEnum.BOM_BILL.getCode(), XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), XbbRefTypeEnum.ASSEMBLE.getCode(),
            XbbRefTypeEnum.INVENTORY.getCode(), XbbRefTypeEnum.TRANSFER.getCode(), XbbRefTypeEnum.STOCK_FLOW_BILL.getCode(),  XbbRefTypeEnum.STOCK_STANDING_BOOK.getCode(),
            XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(), XbbRefTypeEnum.REFUND_INSTOCK.getCode(), XbbRefTypeEnum.OTHER_INSTOCK.getCode(), XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode(),
            XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(),
            XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(), XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode(), XbbRefTypeEnum.WAREHOUSE.getCode(),
            // 资金
            XbbRefTypeEnum.PAYMENT.getCode(), XbbRefTypeEnum.PAYMENT_SHEET.getCode(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), XbbRefTypeEnum.PAY_PLAN.getCode(), XbbRefTypeEnum.PAY_SHEET.getCode(),
            XbbRefTypeEnum.PREPAY_BALANCE.getCode(),  XbbRefTypeEnum.INVOICE.getCode(),  XbbRefTypeEnum.PURCHASE_INVOICE.getCode(),
            XbbRefTypeEnum.PAYMENT_TASK.getCode(),
            XbbRefTypeEnum.ONLINE_PAYMENT_FLOW.getCode(),
            XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode(),
            XbbRefTypeEnum.CUSTOMER_STATEMENT_STATISTIC.getCode(),
            // 信用管理
            XbbRefTypeEnum.CREDIT_LIMIT.getCode(), XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getCode(), XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getCode(), XbbRefTypeEnum.CREDIT_CARD_BILL.getCode(),
            // 其他收入、其他支出、资金调拨
            XbbRefTypeEnum.OTHER_INCOME.getCode(), XbbRefTypeEnum.OTHER_EXPENSE.getCode(), XbbRefTypeEnum.FUND_TRANSFER.getCode(),
            // 产品
            XbbRefTypeEnum.PRODUCT.getCode(),
            // 库存产品
            XbbRefTypeEnum.STOCK_PRODUCT.getCode(),
            // 工单
            XbbRefTypeEnum.WORK_ORDER.getCode(),
            // 批次流水
            XbbRefTypeEnum.BATCH_FLOW_BILL.getCode(),
            // 序列号流水
            XbbRefTypeEnum.SEQ_SEARCH.getCode(),
            // 市场管理
            XbbRefTypeEnum.MARKET_ACTIVITY.getCode(), XbbRefTypeEnum.CLUE.getCode(),
            // 营销管理
            XbbRefTypeEnum.MARKETING_MANAGEMENT.getCode(),
            XbbRefTypeEnum.MARKETING_TOOL.getCode(),
            XbbRefTypeEnum.MARKETING_ACTIVITY_MANAGEMENT.getCode(),
            XbbRefTypeEnum.MARKETING_ACTIVITY.getCode(),
            XbbRefTypeEnum.PROMOTION_TOOL.getCode(),
            XbbRefTypeEnum.PROMOTION_ACTIVITY_MANAGEMENT.getCode(),
            XbbRefTypeEnum.PROMOTION_ACTIVITY.getCode(),
            XbbRefTypeEnum.COST_ADJUST.getCode(),
            // 新工单
            XbbRefTypeEnum.WORK_ORDER_V2.getCode(),
            XbbRefTypeEnum.RECEIPT_ORDER.getCode()
    );

    public static void setEmpty(FieldAttrEntity fieldAttrEntity) {
        setEmptyItem(fieldAttrEntity);
        setDateTypeNull(fieldAttrEntity);
        SetNumLimitNull(fieldAttrEntity);

    }
    public static void setEmptyItem(FieldAttrEntity fieldAttrEntity) {
        if (!ExplainUtil.isCombo(fieldAttrEntity.getFieldType())) {
            fieldAttrEntity.setItems(new ArrayList<>());
        }
    }

    public static void setDateTypeNull(FieldAttrEntity fieldAttrEntity) {
        if (!Objects.equals(FieldTypeEnum.DATETIME.getType(), fieldAttrEntity.getFieldType())) {
            fieldAttrEntity.setDateType(null);
        }
    }
    public static void SetNumLimitNull(FieldAttrEntity fieldAttrEntity) {
        // 非数字类型，不需要限制数据限制
        if (!Objects.equals(FieldTypeEnum.NUM.getType(), fieldAttrEntity.getFieldType())) {
            fieldAttrEntity.setNumericalLimits(null);
        }
    }


    /**
     *  设置字段名称等
     * @param demoEnum
     * @return
     */
    public static FieldAttrEntity setField(DemoEnum demoEnum) {
        FieldAttrEntity fieldAttrEntity = getNewFieldAttrEntity();
        fieldAttrEntity.setAttr(demoEnum.getAttr());
        fieldAttrEntity.setAttrName(demoEnum.getAlias());
        fieldAttrEntity.setSaasAttr(demoEnum.getSaasAttr());
        fieldAttrEntity.setFieldType(demoEnum.getFiledType());
        fieldAttrEntity.setSetType(demoEnum.getSetType());
        fieldAttrEntity.setShowType(demoEnum.getShowType());
        fieldAttrEntity.setEditHide(demoEnum.getEditHide());
        fieldAttrEntity.setEditable(demoEnum.getEditable());
        fieldAttrEntity.setIcon(DemoIconEnum.getIconStr(demoEnum.getFiledType()));
        fieldAttrEntity.setAttrType(FieldTypeEnum.getFieldTypeEnum(demoEnum.getFiledType()).getEsalias());
        return fieldAttrEntity;
    }






    public static FieldAttrEntity setField(Enum anEnum, Integer type){
        RedundantTemplateTypeEnum templateTypeEnum = RedundantTemplateTypeEnum.getByCode(type);
        switch (templateTypeEnum){
            case CUSTOMER:
                CustomerManagementEnum customerManagementEnum = (CustomerManagementEnum)anEnum;
                return setField(customerManagementEnum.getAttr(), customerManagementEnum.getAttrName(), customerManagementEnum.getSaasAttr(), customerManagementEnum.getFieldType(),4,0,0,1);
            case CONTACT:
                ContactEnum contactEnum = (ContactEnum)anEnum;
                return setField(contactEnum.getAttr(),contactEnum.getAttrName(),contactEnum.getSaasAttr(),contactEnum.getFieldType(),4,0,0,1);
            default:
            return getNewFieldAttrEntity();
        }
    }






    public static <T> List<ItemPoJo> setCombItemByEnum(Class<T> clazz, Integer fieldType) {
        return setCombItemByEnum(clazz,fieldType,null,null);
    }

    @Override
    public void beforeSave(){
        //TODO 免费版判断超过1000数据
        //TODO 数据字典校验
        //TODO 关联联系人校验
        //TODO 生日校验
    }

    /**
     * 根据alias获取初始化字段列表
     * 该方法会重载父类方法，不允许删除，可理解为业务层实现
     * @see XbbRefTypeEnum
     * @param alias 业务信息
     * @param productForm
     * @param fundSetTransitionPojo 资金三期需要用到公司id字段，后面其它模块需要添加字段可以往这边添加字段
     * @param distributorMark 经销商业务传1，其他业务传0即可
     * @return 字段信息
     * @throws XbbException 业务异常
     */
    public static List<FieldAttrEntity> initFieldAttrEntity(String alias, PaasFormEntity productForm, FundSetTransitionPojo fundSetTransitionPojo, Integer distributorMark) throws XbbException {
        List<FieldAttrEntity> fieldAttrEntityList = new ArrayList<>();
        try {
            FundSetService fundSetService = (FundSetService) SpringContextUtil.getBean(FUND_SERVICE_BEAN_ID);
            HandleFieldEntity4InitService handleFieldEntity4InitService = (HandleFieldEntity4InitService) SpringContextUtil.getBean(HANDLEFIELDENTITY4INIT_SERVICE_BEAN_ID);
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByAlias(alias);
            FundSetHandleExplainPojo fundSetHandleExplainPojo = fundSetService.getFundSetHandleExplainPojo4Init(fundSetTransitionPojo, xbbRefTypeEnum);
            // 拼装枚举类
            String aliasEnum = "Temp" + alias.substring(0, 1).toUpperCase() + alias.substring(1, alias.length()) + (Objects.equals(distributorMark, 1) ? "Distributor" : "") + "Enum";
            // 拼装包名
            String className = "com.xbongbong.saas.script.tempenum." + aliasEnum;
            // 根据包名拿到对象
            Class clazz = Class.forName(className);
            // 获取getAllEnum方法
            Method method = clazz.getMethod("getAllEnum");
            List<Object> list = (List<Object>) method.invoke(clazz);
            List<String> enumAttrs = null;
            for (Object object : list) {
                // 根据方法getAnEnum拿到对应的枚举类
                Method nameMethod = object.getClass().getMethod("getAnEnum");
                Object anEnum = nameMethod.invoke(object);
                // 包装业务枚举类
                EnumBase<Object> enumBase = new EnumBase<>(anEnum);
                Class<?> enumBaseClazz = enumBase.t.getClass();
                if (enumAttrs == null) {
                    // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
                    enumAttrs = getBusinessEnumAttrs(enumBaseClazz);
                }
                // 初始化字段解释
                FieldAttrEntity fieldAttrEntity = setField(enumBase, enumAttrs);
                if (fieldAttrEntity != null) {
                    String saasAttr = fieldAttrEntity.getSaasAttr();
                    String attr = saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1);
                    String methodName = "init" + attr;
                    try {
                        if (Objects.nonNull(productForm) && Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.SELECT_PRODUCT.getType())){
                            //选择产品字段
                            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
                            BeanUtil.copyProperties(productForm,paasFormEntityExt);
                            paasFormEntityExt.setDistributorMark(distributorMark);
                            if (!Objects.equals(XbbRefTypeEnum.WORK_ORDER.getAlias(),alias)){
                                setSelectProductField(fieldAttrEntity,alias,paasFormEntityExt);
                            }else {
                                setSelectWorkOrderProductField(fieldAttrEntity,paasFormEntityExt);
                            }
                        }
                        Method methodHasParameter = clazz.getMethod(methodName, FieldAttrEntity.class);
                        methodHasParameter.invoke(enumBase, fieldAttrEntity);
                        // 资金三期开票模式下，客户模板或者合同模板应收账期字段必须开启
                        fundSetService.handleFieldEntity4Init(xbbRefTypeEnum, fundSetHandleExplainPojo, fieldAttrEntity);
                        // 特殊处理
                        handleFieldEntity4InitService.handleFieldEntity4Init(fundSetTransitionPojo.getCorpid(), xbbRefTypeEnum, fieldAttrEntity);

                    } catch (NoSuchMethodException e) {
                        // 没有对应字段的初始化方法
                    } catch (Exception e) {
                        e.printStackTrace();
                        LOG.error("InitExplainsHelper.initFieldAttrEntity", e);
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                    }
                    fieldAttrEntityList.add(fieldAttrEntity);
                }
            }
            FieldOptimizationHandle.fieldHandle(fieldAttrEntityList);
        } catch (Exception e) {
            LOG.error("initExplainService.initFiledAttrEntity根据alias获取初始化字段列表报错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return fieldAttrEntityList;
    }

    public static void setSelectProductField(FieldAttrEntity entity, String alias, PaasFormEntityExt productForm) {
        Integer businessType = XbbRefTypeEnum.getByAlias(alias).getCode();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);

        LinkProductInitFieldPoJo linkProductInitFieldPoJo = getLinkProductField(xbbRefTypeEnum, entity);
        Class clazz = linkProductInitFieldPoJo.getClazz();
        Class tempClazz = linkProductInitFieldPoJo.getTempClazz();

        List<FieldAttrEntity> subFieldAttrList = new ArrayList<>();
        List<String> enumAttrs = getBusinessEnumAttrs(clazz);
        Object[] objs = clazz.getEnumConstants();
        for (Object obj : objs) {
            FieldAttrEntity newFieldAttrEntity = setField(clazz, enumAttrs, obj);
            try {
                if (Objects.equals(newFieldAttrEntity.getAttr(), SelectProductEnum.PRODUCT.getAttr())) {
                    //主键字段
                    List<LinkedAttrPoJo> linkedAttrPoJoList = getLinkedAttr(xbbRefTypeEnum);
                    List<LinkedAttrPoJo> linkedShowPoJoList = getLinkedShowAttr(xbbRefTypeEnum);
                    Method method = tempClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class, List.class, List.class,PaasFormEntityExt.class);
                    method.invoke(tempClazz, newFieldAttrEntity, linkedAttrPoJoList,linkedShowPoJoList, productForm);
                } else {
                    Method method = tempClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
                    method.invoke(tempClazz, newFieldAttrEntity);
                    // 经销商业务 数量字段需为整数
                    if (DISTRIBUTOR_BUSINESSTYPE.contains(businessType) && Objects.equals(productForm.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode()) && Objects.equals(newFieldAttrEntity.getAttr(), SelectProductEnum.NUM.getAttr())) {
                        newFieldAttrEntity.setIntegerOnly(1);
                    }
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
//                e.printStackTrace();
            }
            newFieldAttrEntity.setIsForbidden(0);
            newFieldAttrEntity.setIsRedundant(0);
            newFieldAttrEntity.setParentAttr(entity.getAttr());
            subFieldAttrList.add(newFieldAttrEntity);
        }
        SubFormPoJo subFormPoJo = new SubFormPoJo();
        subFormPoJo.setItems(subFieldAttrList);
        LOG.warn("size:" + subFieldAttrList.size());
        entity.setSubForm(subFormPoJo);
        entity.getDefaultAttr().setDefaultType(DefaultTypeEnum.CUSTOM.getAlias());
    }

    /**
     * CRM简化版-根据alias获取初始化字段列表
     * @see XbbRefTypeEnum
     * @param alias 业务信息
     * @param fieldArray 字段镜像
     * @param fundSetTransitionPojo 资金三期需要用到公司id字段，后面其它模块需要添加字段可以往这边添加字段
     * @return 字段信息
     * @throws XbbException 业务异常
     */
    public static List<FieldAttrEntity> initSimpleFieldAttrEntity(String alias, JSONArray fieldArray, PaasFormEntity productForm, FundSetTransitionPojo fundSetTransitionPojo) throws XbbException {
        List<FieldAttrEntity> fieldAttrEntityList = new ArrayList<>();
        try {
            FundSetService fundSetService = (FundSetService) SpringContextUtil.getBean(FUND_SERVICE_BEAN_ID);
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByAlias(alias);
            FundSetHandleExplainPojo fundSetHandleExplainPojo = fundSetService.getFundSetHandleExplainPojo4Init(fundSetTransitionPojo, xbbRefTypeEnum);
            // 拼装枚举类
            alias = "Temp" + alias.substring(0, 1).toUpperCase() + alias.substring(1, alias.length()) + "Enum";
            // 拼装包名
            String className = "com.xbongbong.saas.script.tempenum." + alias;
            // 根据包名拿到对象
            Class clazz = Class.forName(className);
            // 获取getAllEnum方法
            Method method = clazz.getMethod("getAllEnum");
            List<Object> list = (List<Object>) method.invoke(clazz);
            List<String> enumAttrs = null;
            for (Object object : list) {
                // 根据方法getAnEnum拿到对应的枚举类
                Method nameMethod = object.getClass().getMethod("getAnEnum");
                Object anEnum = nameMethod.invoke(object);
                // 包装业务枚举类
                EnumBase<Object> enumBase = new EnumBase<>(anEnum);
                Class<?> enumBaseClazz = enumBase.t.getClass();
                if (enumAttrs == null) {
                    // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
                    enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(enumBaseClazz);
                }
                // 排除不需要的字段
                Method attrMethod = enumBaseClazz.getMethod("getAttr");
                Object attrName = attrMethod.invoke(enumBase.t);
                // 初始化字段解释
                FieldAttrEntity fieldAttrEntity = InitExplainsHelper.setField(enumBase, enumAttrs);
                if (fieldAttrEntity != null) {
                    String saasAttr = fieldAttrEntity.getSaasAttr();
                    String attr = saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1);
                    String methodName = "init" + attr;
                    try {
                        if (Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.SELECT_PRODUCT.getType())){
                            //选择产品字段
                            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
                            BeanUtil.copyProperties(productForm,paasFormEntityExt);
                            if (!Objects.equals(XbbRefTypeEnum.WORK_ORDER.getAlias(),alias)){
                                InitExplainsHelper.setSelectProductField(fieldAttrEntity,alias,paasFormEntityExt);
                            }else {
                                InitExplainsHelper.setSelectWorkOrderProductField(fieldAttrEntity,paasFormEntityExt);
                            }
                        }
                        if (Objects.equals(attr, "Phone")) {
                            // 电话比较特殊，直接存的是 "subForm_1.text_1", "subForm_1.text_2"
                            Method methodHasParameter = clazz.getMethod(methodName, FieldAttrEntity.class, JSONArray.class);
                            methodHasParameter.invoke(enumBase, fieldAttrEntity, fieldArray);
                        } else {
                            Method methodHasParameter = clazz.getMethod(methodName, FieldAttrEntity.class);
                            methodHasParameter.invoke(enumBase, fieldAttrEntity);
                        }
                        // 资金三期开票模式下，客户模板或者合同模板应收账期字段必须开启
                        fundSetService.handleFieldEntity4Init(xbbRefTypeEnum, fundSetHandleExplainPojo, fieldAttrEntity);
                    } catch (NoSuchMethodException e) {
                        // 没有对应字段的初始化方法
                    } catch (Exception e) {
                        LOG.error(e.getMessage());
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                    }
                    if (fieldArray != null) {
                        // 镜像中不存在的字段，默认不开启 （fieldArray等于null时表示没有配置该模块，初始化解释时按默认的）
                        boolean phoneFlag = Objects.equals(attrName, "subForm_1") && (fieldArray.contains("subForm_1.text_1") || fieldArray.contains("subForm_1.text_2"));
                        if (!fieldArray.contains(attrName.toString()) && !phoneFlag && Objects.equals(fieldAttrEntity.getEditHide(), 0)) {
                            fieldAttrEntity.setIsOpen(0);
                        }
                    }
                    fieldAttrEntityList.add(fieldAttrEntity);
                }
            }
        } catch (Exception e) {
            LOG.error("initExplainService.initSimpleFieldAttrEntity根据alias获取初始化字段列表报错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return fieldAttrEntityList;
    }

    private static void setWorkOrderSelectProductField(FieldAttrEntity fieldAttrEntity, String alias, PaasFormEntity productForm) {
    }





    public static LinkProductInitFieldPoJo getLinkProductField(XbbRefTypeEnum xbbRefTypeEnum, FieldAttrEntity entity) {
        Class clazz = null;
        Class tempClazz = null;
        switch (xbbRefTypeEnum) {
            case CONTRACT:
                clazz = ContractProductEnum.class;
                tempClazz = TempContractProductEnum.class;
                break;
            case REFUND:
                clazz = RefundProductEnum.class;
                tempClazz = TempRefundProductEnum.class;
                break;
            case SALES_OPPORTUNITY:
                clazz = OpportunityProductEnum.class;
                tempClazz = TempOpportunityProductEnum.class;
                break;
            case SUPPLIER:
                clazz = SupplierProductEnum.class;
                tempClazz = TempSupplierProductEnum.class;
                break;
            case PURCHASE:
                clazz = PurchaseProductEnum.class;
                tempClazz = TempPurchaseProductEnum.class;
                break;
            case RETURNED_PURCHASE:
                clazz = ReturnPurchaseProductEnum.class;
                tempClazz = TempReturnPurchaseProductEnum.class;
                break;
            case ASSEMBLE:
                if (Objects.equals(AssembleEnum.IN_PRODUCTS.getAttr(),entity.getAttr())){
                    clazz = AssembleInProductEnum.class;
                    tempClazz = TempAssembleInProductEnum.class;
                }else {
                    clazz = AssembleProductEnum.class;
                    tempClazz = TempAssembleProductEnum.class;
                }
                break;
            case OTHER_INSTOCK:
                clazz = InstockProductEnum.class;
                tempClazz = TempInstockProductEnum.class;
                break;
            case PURCHASE_INSTOCK:
                clazz = PurchaseInstockProductEnum.class;
                tempClazz = TempPurchaseInstockProductEnum.class;
                break;
            case REFUND_INSTOCK:
                clazz = RefundInstockProductEnum.class;
                tempClazz = TempRefundInstockProductEnum.class;
                break;
            case PRODUCTION_INSTOCK:
                clazz = ProductionInstockProductEnum.class;
                tempClazz = TempProductionInstockProductEnum.class;
                break;
            case RETURNED_MATERIEL_INSTOCK:
                clazz = ReturnedMaterielInstockProductEnum.class;
                tempClazz = TempReturnedMaterielInstockProductEnum.class;
                break;
            case OTHER_OUTSTOCK:
                clazz = OutstockProductEnum.class;
                tempClazz = TempOutstockProductEnum.class;
                break;
            case CONTRACT_OUTSTOCK:
                clazz = ContractOutstockProductEnum.class;
                tempClazz = TempContractOutstockProductEnum.class;
                break;
            case CUSTOMER_STATEMENT:
                clazz = CustomerStatementProductEnum.class;
                tempClazz = TempCustomerStatementProductEnum.class;
                break;
            case RETURNED_PURCHASE_OUTSTOCK:
                clazz = ReturnedPurchaseOutstockProductEnum.class;
                tempClazz = TempReturnedPurchaseOutstockProductEnum.class;
                break;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                clazz = ProductionMaterielOutstockProductEnum.class;
                tempClazz = TempProductionMaterielOutstockProductEnum.class;
                break;
            case WORK_ORDER_OUTSTOCK:
                clazz = WorkOrderOutstockProductEnum.class;
                tempClazz = TempWorkOrderOutstockProductEnum.class;
                break;
            case INVENTORY:
                clazz = InventoryProductEnum.class;
                tempClazz = TempInventoryProductEnum.class;
                break;
            case TRANSFER:
                clazz = TransferProductEnum.class;
                tempClazz = TempTransferProductEnum.class;
                break;
            case WORK_ORDER:
                clazz = WorkOrderProductEnum.class;
                tempClazz = TempWorkOrderProductEnum.class;
                break;
            case BOM_BILL:
                if (Objects.equals(BomBillEnum.PRODUCT.getAttr(),entity.getAttr())){
                    // 成品只能有一个
                    entity.setIsSingleRow(1);
                    clazz = BomFinishProductEnum.class;
                    tempClazz = TempBomFinishProductEnum.class;
                }else if (Objects.equals(BomBillEnum.MATERIEL.getAttr(),entity.getAttr())){
                    clazz = BomMaterielProductEnum.class;
                    tempClazz = TempBomMaterieProductEnum.class;
                }
                break;
            case PRODUCTION_ORDER:
                if (Objects.equals(ProductionOrderEnum.PRODUCT.getAttr(),entity.getAttr())){
                    entity.setEditable(0);
                    clazz = ProductionOrderFinishProductEnum.class;
                    tempClazz = TempProductionOrderFinishProductEnum.class;
                }else if (Objects.equals(ProductionOrderEnum.MATERIEL.getAttr(),entity.getAttr())){
                    entity.setEditable(0);
                    clazz = ProductionOrderMaterielProductEnum.class;
                    tempClazz = TempProductionOrderMaterieProductEnum.class;
                }
                break;
            case ORI_STOCK:
                clazz = OriStockProductEnum.class;
                tempClazz = TempOriStockProductEnum.class;
                break;
            case QUOTATION:
                clazz = QuotationProductEnum.class;
                tempClazz = TempQuotationProductEnum.class;
                break;
            case PROMOTION_ACTIVITY_MANAGEMENT:
                clazz = PromotionActivityManagementProductEnum.class;
                tempClazz = TempPromotionActivityManagementProductEnum.class;
                break;
            case COST_ADJUST:
                clazz = CostAdjustProductEnum.class;
                tempClazz = TempCostAdjustProductEnum.class;
                break;
            default:
                break;
        }
        return new LinkProductInitFieldPoJo(clazz, tempClazz);
    }

    public static void setSelectWorkOrderProductField(FieldAttrEntity entity, PaasFormEntityExt productForm) {
        Class clazz = WorkOrderProductEnum.class;
        Class tempClazz = TempWorkOrderProductEnum.class;
        List<FieldAttrEntity> subFieldAttrList = new ArrayList<>();
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
        Object[] objs = clazz.getEnumConstants();
        for (Object obj : objs) {
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(clazz, enumAttrs, obj);
            try {
                if (Objects.equals(newFieldAttrEntity.getAttr(), ContractProductEnum.PRODUCT.getAttr())) {
                    //主键字段
                    List<LinkedAttrPoJo> linkedAttrPoJoList = getLinkedAttr(XbbRefTypeEnum.WORK_ORDER);
                    List<LinkedAttrPoJo> linkedShowPoJoList = getLinkedShowAttr(XbbRefTypeEnum.WORK_ORDER);
                    Method method = tempClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class, List.class,List.class, PaasFormEntityExt.class);
                    method.invoke(tempClazz, newFieldAttrEntity, linkedAttrPoJoList, linkedShowPoJoList, productForm);
                } else {
                    Method method = tempClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
                    method.invoke(tempClazz, newFieldAttrEntity);
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            newFieldAttrEntity.setIsForbidden(0);
            newFieldAttrEntity.setIsRedundant(0);
            newFieldAttrEntity.setVisible(1);
            newFieldAttrEntity.setParentAttr(entity.getAttr());
            subFieldAttrList.add(newFieldAttrEntity);
        }
        SubFormPoJo subFormPoJo = new SubFormPoJo();
        subFormPoJo.setItems(subFieldAttrList);
        LOG.warn("size:" + subFieldAttrList.size());
        entity.setSubForm(subFormPoJo);
        entity.getDefaultAttr().setDefaultType(DefaultTypeEnum.CUSTOM.getAlias());
    }

    public static List<LinkedAttrPoJo> getLinkedAttr(XbbRefTypeEnum xbbRefTypeEnum) {
        List<ProductEnum> productEnumList = getProductEnumList(xbbRefTypeEnum);
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(ProductEnum.class);
        List<LinkedAttrPoJo> linkedAttrPoJoList = new ArrayList<>();
        for (ProductEnum productEnum : productEnumList){
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(ProductEnum.class, enumAttrs,productEnum);
            try {
                Method method = TempProductEnum.class.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1),FieldAttrEntity.class);
                method.invoke(TempProductEnum.class,newFieldAttrEntity);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
//                e.printStackTrace();
            }
            newFieldAttrEntity.setVisible(1);
            LinkedAttrPoJo linkedAttrPoJo = new LinkedAttrPoJo();
            BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
            linkedAttrPoJoList.add(linkedAttrPoJo);
        }
        /*if (Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.REFUND) || Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.RETURNED_PURCHASE) || Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK)) {
            LinkedAttrPoJo linkedAttrPoJo = new LinkedAttrPoJo();
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
            BeanUtil.copyProperties(SelectProductEnum.SOURCE_DOC,newFieldAttrEntity);
            BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
            linkedAttrPoJoList.add(0, linkedAttrPoJo);
        }
        addSpecialLinkedAttrPoJo(linkedAttrPoJoList, xbbRefTypeEnum);*/
        return linkedAttrPoJoList;
    }

    public static void addSpecialLinkedAttrPoJo(List<LinkedAttrPoJo> linkedAttrPoJoList, XbbRefTypeEnum xbbRefTypeEnum) {
        switch (xbbRefTypeEnum) {
            case CONTRACT_OUTSTOCK:
                LinkedAttrPoJo linkedAttrPoJo = new LinkedAttrPoJo();
                FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                BeanUtil.copyProperties(ContractProductEnum.SELLING_PRICE,newFieldAttrEntity);
                BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                linkedAttrPoJoList.add(linkedAttrPoJo);
                break;
            case RETURNED_PURCHASE_OUTSTOCK:
                linkedAttrPoJo = new LinkedAttrPoJo();
                newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                BeanUtil.copyProperties(ReturnPurchaseProductEnum.PURCHASE_PRICE,newFieldAttrEntity);
                BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                linkedAttrPoJoList.add(linkedAttrPoJo);
                break;
            case WORK_ORDER_OUTSTOCK:
                linkedAttrPoJo = new LinkedAttrPoJo();
                newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                BeanUtil.copyProperties(WorkOrderProductEnum.PRICE,newFieldAttrEntity);
                BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                linkedAttrPoJoList.add(linkedAttrPoJo);
                break;
            case PURCHASE_INSTOCK:
                linkedAttrPoJo = new LinkedAttrPoJo();
                newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                BeanUtil.copyProperties(PurchaseProductEnum.PURCHASE_PRICE,newFieldAttrEntity);
                BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                linkedAttrPoJoList.add(linkedAttrPoJo);
                break;
            case REFUND_INSTOCK:
                linkedAttrPoJo = new LinkedAttrPoJo();
                newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                BeanUtil.copyProperties(RefundProductEnum.PRICE,newFieldAttrEntity);
                BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                linkedAttrPoJoList.add(linkedAttrPoJo);
                break;
            case REFUND:
                linkedAttrPoJo = new LinkedAttrPoJo();
                newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                BeanUtil.copyProperties(ContractOutstockProductEnum.SELLING_PRICE,newFieldAttrEntity);
                BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                linkedAttrPoJoList.add(linkedAttrPoJo);
                break;
            case RETURNED_PURCHASE:
                linkedAttrPoJo = new LinkedAttrPoJo();
                newFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                BeanUtil.copyProperties(PurchaseInstockProductEnum.COST,newFieldAttrEntity);
                BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                linkedAttrPoJoList.add(linkedAttrPoJo);
                break;
            default:
                break;
        }
        switch (xbbRefTypeEnum) {
            case OTHER_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case OTHER_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case REFUND_INSTOCK:
            case REFUND:
            case RETURNED_PURCHASE:
                List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(SelectProductEnum.class);
                for (SelectProductEnum selectProductEnum : Arrays.asList(SelectProductEnum.BATCH, SelectProductEnum.PRODUCE_DATE, SelectProductEnum.GUARANTEE_PERIOD)){
                    FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(SelectProductEnum.class, enumAttrs, selectProductEnum);
                    /*try {
                        Method method = SelectProductEnum.class.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1),FieldAttrEntity.class);
                        method.invoke(SelectProductEnum.class,newFieldAttrEntity);
                    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                    }*/
                    newFieldAttrEntity.setVisible(1);
                    LinkedAttrPoJo linkedAttrPoJo = new LinkedAttrPoJo();
                    BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
                    linkedAttrPoJoList.add(linkedAttrPoJo);
                }
                break;
            default:
                break;
        }
    }

    private static List<ProductEnum> getProductEnumList(XbbRefTypeEnum xbbRefTypeEnum) {
        List<ProductEnum> productEnums = null;
        switch (xbbRefTypeEnum) {
            case CONTRACT:
            case SALES_OPPORTUNITY:
            case PURCHASE:
            case ASSEMBLE:
            case INSTOCK:
            case OUTSTOCK:
            case INVENTORY:
            case TRANSFER:
            case WORK_ORDER:
            case BOM_BILL:
            case PRODUCTION_ORDER:
            case ORI_STOCK:
            case QUOTATION:
                productEnums = Arrays.asList(ProductEnum.PRODUCT_IMGS, ProductEnum.NAME, ProductEnum.SERIALNO, ProductEnum.SPECIFICATION, ProductEnum.STOCK, ProductEnum.UNIT);
                break;
            case SUPPLIER:
                productEnums = Arrays.asList(ProductEnum.PRODUCT_IMGS, ProductEnum.NAME, ProductEnum.SERIALNO, ProductEnum.SPECIFICATION, ProductEnum.COST, ProductEnum.PRICE, ProductEnum.UNIT);
                break;
            case CONTRACT_OUTSTOCK:
            case OTHER_INSTOCK:
            case OTHER_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case REFUND:
            case RETURNED_PURCHASE:
            case PROMOTION_ACTIVITY_MANAGEMENT:
                productEnums = Arrays.asList(ProductEnum.NAME, ProductEnum.SERIALNO, ProductEnum.SPECIFICATION, ProductEnum.PRODUCT_IMGS);
                break;
            case CUSTOMER_STATEMENT:
                productEnums = Arrays.asList(ProductEnum.NAME, ProductEnum.SERIALNO, ProductEnum.SPECIFICATION);
                break;
            case COST_ADJUST:
                productEnums = Arrays.asList(ProductEnum.NAME, ProductEnum.PRODUCT_IMGS, ProductEnum.SERIALNO, ProductEnum.SPECIFICATION, ProductEnum.STOCK, ProductEnum.UNIT);
                break;
            default:
                break;
        }
        return productEnums;
    }

    private static List<LinkedAttrPoJo> getLinkedShowAttr(XbbRefTypeEnum xbbRefTypeEnum) {
        List<ProductEnum> productEnumList = getShowProductEnumList(xbbRefTypeEnum);
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(ProductEnum.class);
        List<LinkedAttrPoJo> linkedAttrPoJoList = new ArrayList<>();
        for (ProductEnum productEnum : productEnumList){
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(ProductEnum.class, enumAttrs,productEnum);
            try {
                Method method = TempProductEnum.class.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1),FieldAttrEntity.class);
                method.invoke(TempProductEnum.class,newFieldAttrEntity);

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            newFieldAttrEntity.setVisible(1);
            LinkedAttrPoJo linkedAttrPoJo = new LinkedAttrPoJo();
            BeanUtil.copyProperties(newFieldAttrEntity,linkedAttrPoJo);
            linkedAttrPoJoList.add(linkedAttrPoJo);
        }
        return linkedAttrPoJoList;
    }

    private static List<ProductEnum> getShowProductEnumList(XbbRefTypeEnum xbbRefTypeEnum) {
        List<ProductEnum> productEnums = null;
        switch (xbbRefTypeEnum) {
            case CONTRACT:
            case SALES_OPPORTUNITY:
            case RETURNED_PURCHASE:
            case REFUND:
            case PURCHASE:
            case ASSEMBLE:
            case OTHER_INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case PRODUCTION_INSTOCK:
            case OTHER_OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case INVENTORY:
            case TRANSFER:
            case WORK_ORDER:
            case BOM_BILL:
            case PRODUCTION_ORDER:
            case ORI_STOCK:
            case SUPPLIER:
            case QUOTATION:
            case PROMOTION_ACTIVITY_MANAGEMENT:
            case COST_ADJUST:
                productEnums = Arrays.asList(ProductEnum.SERIALNO, ProductEnum.SPECIFICATION);
                break;
            case CUSTOMER_STATEMENT:
                productEnums = Arrays.asList(ProductEnum.SERIALNO, ProductEnum.SPECIFICATION);
                break;
            default:
                break;
        }
        return productEnums;
    }


    /**
     * 修改字段属性值,，用于国际化脚本
     * @param alias
     * @param fieldList
     */
    public static void updateFieldAttrEntity(String alias, List<FieldAttrEntity> fieldList) {
        try {
            // 拼装枚举类
            String aliasEnum = "Temp" + alias.substring(0, 1).toUpperCase() + alias.substring(1, alias.length()) + "Enum";
            // 拼装包名
            String className = "com.xbongbong.saas.script.tempenum." + aliasEnum;
            // 根据包名拿到对象
            Class clazz = Class.forName(className);
            // 获取getAllEnum方法
            Method method = clazz.getMethod("getAllEnum");
            List<Object> list = (List<Object>) method.invoke(clazz);
            List<String> enumAttrs = null;
            for (Object object : list) {
                // 根据方法getAnEnum拿到对应的枚举类
                Method nameMethod = object.getClass().getMethod("getAnEnum");
                Object anEnum = nameMethod.invoke(object);
                // 包装业务枚举类
                EnumBase<Object> enumBase = new EnumBase<>(anEnum);
                Class<?> enumBaseClazz = enumBase.t.getClass();
                if (enumAttrs == null) {
                    // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
                    enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(enumBaseClazz);
                }
                for (FieldAttrEntity fieldAttrEntity : fieldList) {
                    Method method0 = enumBaseClazz.getMethod("getAttr");
                    Object value0 = method0.invoke(enumBase.t);
                    if (Objects.equals(value0.toString(), fieldAttrEntity.getAttr())) {
                        Method method1 = enumBaseClazz.getMethod("getAttrName");
                        Object value1 = method1.invoke(enumBase.t);
                        Method method2 = FieldAttrEntity.class.getMethod("setAttrNameEn", String.class);
                        method2.invoke(fieldAttrEntity,value1.toString());
                    }
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            LOG.error(alias + "赋值出错");
        }

    }

}
